﻿# -*- coding:utf-8 -*-
#
# FileDownload 
# Скачивание файлов
#
from django.conf import settings
from datetime import datetime, timedelta
from time import sleep
# import models
from django.contrib.auth.models import User
# import django functions
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.template import RequestContext, Context
# import decorators
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required
try:
    from functools import wraps
except:
    from django.utils.functional import wraps # python 2.3, 2.4
# import filesystem and others main modules
import os, mimetypes
#import fmoper
import pickle
import operator
from django.utils import simplejson
from django.core.servers.basehttp import FileWrapper
from django.core.files.storage import FileSystemStorage

#from django.template.defaultfilters import slugify

from urlparse import urljoin
import utils



###                 Decorators              ###


def render_to(request, template, context):
    context_extra = Context({
        'dummy': '',
    })
    return render_to_response('filedownload/'+template, context, context_instance=RequestContext(request, context_extra))    
    

@permission_required('fileman.can_fm_list')
def fd_index(request,path=None):   #, path=None
    """ Render file list """
    #
    storage = utils.Directory('')
    dirnode = storage.collect_dirs()
    #
    objlist = storage.collect_files()
    #        
    context = Context({
        "pwd": path,
        "dirnode": dirnode,
        "objlist":objlist,
    })
    return render_to(request, 'index.html', context)           


@permission_required('fileman.can_fm_list')
def dirtree_node(request, path=None):
    """ Render Directory tree node """
    storage = utils.Directory(path)
    dirnode = storage.collect_dirs()    
    context = Context({
        "pwd": path,
        "dirnode": dirnode,
    })
    return render_to(request, 'treeview_node.html', context)  


@permission_required('fileman.can_fm_list')
def ajax_ls(request, path=None):
    """ Render file list """
    storage = utils.Directory(path)
    objlist = storage.collect_files()
    context = Context({
        "pwd": path,
        "objlist":objlist,
    })
    return render_to(request, 'listview_items.html', context)         
    
    

SECOND = timedelta(seconds=1)
BANDWIDTH = 512

def output(file, first):
    last_time = datetime.now()
    file.seek (first)
    while True:
        time_passed = datetime.now() - last_time
        if time_passed < SECOND:
            sleep((SECOND - time_passed).microseconds / 1000000.0)
        last_time = datetime.now()

        content = file.read(BANDWIDTH)
        if not content:
            break
        yield content

  
def parse_range(http_range, file_size):
    http_range = http_range.split('=') 
    bits=http_range[1].split('-')
    if bits[0]: # normal range
        first = int(bits[0])
        last = bits[1] and int(bits[1]) or file_size-1
    else: # suffix range
        first = file_size - int(bits[1])
        last = file_size - 1
    return (first, last)




#@permission_required('fileman.can_fm_list')
def download(request, path=None):

    file_name =  os.path.basename(path)
    path = os.path.dirname(path)

    rel_dir = (path+"/").lstrip('/')
    directory = os.path.join(settings.FILEDOWNLOAD_MEDIA_DIRECTORY, rel_dir)
    url = urljoin(settings.MEDIA_URL, rel_dir)    
    storage = FileSystemStorage(directory, url)
    file  = storage.open(file_name)
    file_size = storage.size(file_name)

    # range 
    range_first = 0
    range_last = 0
    range_len = 0
    if request.META.has_key('HTTP_RANGE'):
        range_first, range_last = parse_range(request.META['HTTP_RANGE'],  file_size)
        range_len = range_last - range_first + 1
    
    # Тип миме
    mimetype, encoding = mimetypes.guess_type(file_name, False)
    # generate the file
    response = HttpResponse(output(file, range_first), content_type=mimetype)
    name, ext = os.path.splitext(file_name)
    response['Content-Disposition'] = 'attachment; filename=%s%s' % (name.encode('cp1251','ignore'), ext.encode('cp1251','ignore'))
    # докачка  
    if range_len != 0:
        HttpResponse.status_code = 206
        response['Content-Range'] = "bytes %d-%d/%d" % (range_first, range_last, file_size)
        response['Content-Length'] = range_len
    else:
        HttpResponse.status_code = 200
        response['Content-Length'] = file_size

    return response
























# import internationalization
#from django.utils.translation import ugettext as _
#if PYTILS:
#    from pytils.translit import slugify
#else:
#    from django.template.defaultfilters import slugify


'''    
def get_num_dir(path):
    count = 0
    for f in os.listdir(path):
        if os.path.isdir(os.path.join(path, f)):
            count += 1 
    return count
'''


'''
def rightPath(canNone=False):
    def decor(fn):
        @wraps(fn)
        def wrapper(request, *args, **kw):
            path = None
            if "path" in kw:
                path = kw["path"]
            if path is None and len(args)>0:
                path = args[0]
            if path is None:
                if canNone:
                    #path = request.user.fileman_Setting.home
                    path = ROOT_PATH
                    kw["path"] = path
                else:
                    return raise_error(request,
                        [_(u"Path does not set.")])
            #if request.user.fileman_Setting.home is None or request.user.fileman_Setting.root is None:
            #    return raise_error(request,
            #        [_(u"Root or home directory is not set.")])
            #root = request.user.fileman_Setting.root
            root = ROOT_PATH
            path = unicode(path)
            if not path.startswith(root):
                return raise_error(request,
                    [_(u"No access")])
            if not os.path.exists(path):
                return raise_error(request,
                    [_(u"Path does not exist.")])
            return fn(request, *args, **kw)
        return wrapper
    return decor
'''


'''    
def get_dirnode(path):    
    dirnode = []
    path = unicode(path)
    for f in os.listdir(path):
        node = {}
        #f = f.decode("cp1251")
        itempath = os.path.join(path, f)
        if os.path.isdir(itempath):
            node['path'] = itempath.replace('\\', '/')
            node['level_div'] = range(0)
            node['name'] = node['path'].split('/')[-1:][0]
            node['child'] = get_num_dir(node['path'])
            node['depth'] = len(node['path'].split('/'))
            dirnode.append(node)    
    return dirnode

def get_listdir(path):
    dirnode = get_dirnode(path)  
    #path = toString(path)
    dirlist = []
    filelist = []
    path = unicode(path)
    print path
    for f in os.listdir(path):
        #f = toString(f)
        #f = f.decode("cp1251")
        #print u'%s' % f
        file = utils.File(f, u"%s/%s" % (path, f))
        try: 
            itemstat = os.stat(os.path.join(path, f))
            #item['ctime'] = datetime.fromtimestamp(itemstat.st_ctime)
            file.modifed = datetime.fromtimestamp(itemstat.st_mtime)          
        except:
            file.modifed = None
        if os.path.isdir(os.path.join(path, f)):
            file.isdir = 1
            file.size = "Dir"
            dirlist.append(file)
        else:
            file.isdir = 0
            file.size = os.path.getsize(os.path.join(path, f))
            filelist.append(file)
        dirlist.sort()
        filelist.sort()
    
    return dirlist+filelist
'''